A frequency divider reduces a base clock frequency into smaller frequencies. This is useful when a system has a single clock source but multiple peripherals require different clock rates.


Block Diagram

Frequency Divider.jpg


Divider Decoder

No. Final Frequency (Hz) (Base = 50 MHz) Factor
0 1/4 200 M
1 1/3 150 M
2 1/2 100 M
3 1 50 M
4 2 25 M
5 3 16.67 M
6 5 10 M
7 8 6.25 M

This can be implemented using a case statement, similar to a 4 Bit Priority Encoder.

module Div_Dec(Din, Dout);

input [2:0]Din;
output reg [31:0];

always @(Din)begin
case (Din)
3'd0:
	Dout = 32'd200000000
3'd1:
	Dout = 32'd150000000
3'd2:
	Dout = 32'd100000000
3'd3:
	Dout = 32'd50000000
3'd4:
	Dout = 32'd25000000
3'd5:
	Dout = 32'd16670000
3'd6:
	Dout = 32'd10000000
3'd7:
	Dout = 32'd6250000
end

Accumulator

The accumulator counts clock cycles and resets when it reaches a target count.

32-bit D Flip-Flop

module DFF32(Din, clk, w_en, reset, Dout);

input [31:0]Din;
input clk, w_en, reset, reset_external;
output reg [31:0]Dout;

always @(posedge clk or negedge reset or negedge reset_external) begin
    if (!reset_external) begin
        Dout <= 32'd0;
    end else if (!reset) begin
        Dout <= 32'd0;
    end else if (w_en) begin
        Dout <= Din;
    end
end

endmodule

32-bit Accumulator

module Acc32(clk, w_en, reset, Acc_out);

input clk, w_en, reset;
output [31:0]Acc_out;

wire [31:0]Din;

assign Din = Acc_out + 32'd1;

DFF32 DFF32_0(.Din(Din), .clk(clk), .w_en(1'd1), .reset(reset), .Dout(Acc_out));

endmodule

Frequency Divider Module

module FDiv(Fin,Fsel,Fout);

input Fin;
input [2:0]Fsel;

wire reset, F_t;
wire [31:0]Dout_h, Dout, Acc_out;

reg Fout;

assign reset = (Acc_out >= Dout);
assign Dout_h = {1'b0, Dout[31:1]};
assign F_t = (Acc_out > Dout_h);

Acc32 Acc_0(.clk(Fin), .w_en(1'b1), .reset(reset), Acc_out(Acc_out));
Div_Dec(.Din(Fsel), .Dout(Dout));

always @(posedge Fin) begin
	Fout <= F_t;
end